class LazyMain{
  constructor(name) {
    this.tasks = []
    this.taskIsRun = false
    this._addTask(() => Promise.resolve(console.log(`Hi, This is ${name}`)))
  }
  async _run() {
    if (this.taskIsRun) {
      return
    }
    this.taskIsRun = true
    while(this.tasks.length > 0) {
      const task = this.tasks.shift()
      await task()
    }
    this.taskIsRun = false
  }
  _nextTick(func) {
    setTimeout(func, 0)
  }
  _addTask(task, isFirst) {
    if (isFirst) {
      this.tasks.unshift(task)
    } else {
      this._nextTick(() => this.tasks.push(task))
    }
    this._nextTick(() => this._run())
  }
  sleep(seconds, isFirst) {
    const func = () => new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log(`Wake up after ${seconds}`)
        resolve()
      }, seconds * 1000)
    })
    this._addTask(func, isFirst)
    return this
  }
  sleepFirst(seconds) {
    return this.sleep(seconds, true)
  }
  eat(food) {
    this._addTask(() => Promise.resolve(console.log(`Eat ${food}`)))
    return this
  }
}
export default name => new LazyMain(name)